package com.dau.service.customer.order.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dau.common.util.RabbitTemplateUntil;
import com.dau.common.util.RabbitUtil;
import com.dau.common.util.RedisUtils;
import com.dau.entity.customer.ItemInfo;
import com.dau.entity.customer.OrderInfo;
import com.dau.entity.system.coupon.CouponInfo;
import com.dau.entity.system.goods.GoodsInfo;
import com.dau.mapper.mapper.order.OrderMapper;
import com.dau.service.customer.item.ItemService;
import com.dau.service.customer.order.OrderService;
import com.dau.service.system.coupon.CouponService;
import com.dau.service.system.goods.GoodsService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Date;
import java.util.List;

/**
 * 角色服务impl
 *
 * @author tzj
 * @date 2024/11/07
 */
@Service("orderService")
@Slf4j
public class OrderServiceImpl extends ServiceImpl<OrderMapper, OrderInfo> implements OrderService {
    @Resource
    private OrderMapper orderMapper;
    @Resource
    private ItemService itemService;
    @Resource
    private GoodsService goodsService;
    @Resource
    private CouponService couponService;
    @Resource
    private RabbitTemplate rabbitTemplate;
    @Resource
    private StringRedisTemplate stringRedisTemplate;
    @Resource
    private RabbitTemplateUntil redisTemplateUntil;

    /**
     * 下订单
     *
     * @param orderInfo 订单信息
     * @return {@link OrderInfo }
     */
    @Override
    public OrderInfo placeAnOrder(OrderInfo orderInfo) {
        RLock lock = RedisUtils.getClient().getLock("order:" + orderInfo.getCustomerId());
        try {
            // 获取锁
            lock.lock();
            List<ItemInfo> itemList = orderInfo.getItmeList();
            checkParam(orderInfo, itemList);
            orderInfo.setOrderId(Long.valueOf(IdWorker.getIdStr()));
            orderInfo.setCustomerVxId("1L");
            orderInfo.setCreateTime(new Date());
            orderInfo.setStatus("0");
            orderInfo.setCreateUser("1L");
            orderMapper.insert(orderInfo);
            for (ItemInfo itemInfo : itemList) {
                itemInfo.setCreateTime(new Date());
                itemInfo.setCreateUser("1L");
                itemInfo.setOrderId(orderInfo.getOrderId());
                itemInfo.setOrderCode(orderInfo.getOrderCode());
                itemInfo.setCustomerId(orderInfo.getCustomerId());
                itemInfo.setCustomerName(orderInfo.getCustomerName());
                itemInfo.setCustomerVxId(orderInfo.getCustomerVxId());
                GoodsInfo goods = goodsService.getById(itemInfo.getGoodsId());
                itemInfo.setGoodsTotal(goods.getPrice().multiply(new BigDecimal(itemInfo.getGoodsNum())));
                itemService.save(itemInfo);
            }
            try {
                String messageData = JSONUtil.toJsonStr(orderInfo);
                redisTemplateUntil.sendDelayedMessage(RabbitUtil.DELAY_EXCHANGE_NAME, RabbitUtil.DELAY_KEY_NAME, messageData, "1000");
            } catch (Exception e) {
                log.error("发送mq错误,order.id ---> {},错误原因--->{}", orderInfo.getOrderId(), e.getMessage());
            }
        } finally {
            // 释放锁
            if (lock.isHeldByCurrentThread()) {
                lock.unlock();
            }
        }
        return null;
    }

    /**
     * 检查参数
     *
     * @param itemList 订单列表
     */
    private void checkParam(OrderInfo orderInfo, List<ItemInfo> itemList) {
        if (CollectionUtils.isEmpty(itemList)) {
            throw new RuntimeException("订单详情不能为空");
        }
        //传值 订单总价
        BigDecimal orderAmount = orderInfo.getOrderAmount().setScale(2, RoundingMode.HALF_UP);
        //计算 订单总价
        BigDecimal totalAmount = BigDecimal.ZERO;
        //商品列表
        for (ItemInfo itemInfo : itemList) {
            //商品
            GoodsInfo goods = goodsService.getById(itemInfo.getGoodsId());
            if (ObjectUtil.isNull(goods)) {
                throw new RuntimeException("商品不存在");
            }
            //商品优惠券
            if (ObjectUtil.isNotNull(itemInfo.getCouponId())) {
                CouponInfo couponInfo = couponService.getById(itemInfo.getCouponId());
                if (couponInfo == null) {
                    throw new RuntimeException("优惠券不存在");
                }
                if (!couponInfo.getAmount().equals(itemInfo.getCouponAmount()) && !itemInfo.getCouponAmount().equals(BigDecimal.ZERO)) {
                    throw new RuntimeException("优惠券价格错误");
                }
                itemInfo.setCouponAmount(couponInfo.getAmount());
            } else {
                if (itemInfo.getCouponAmount().compareTo(BigDecimal.ZERO) > 0) {
                    throw new RuntimeException("缺少商品优惠券信息");
                }
            }
            //商品数量
            int goodsNum = itemInfo.getGoodsNum();
            if (goodsNum <= 0 && isNumeric(goodsNum + "")) {
                throw new RuntimeException("商品数量错误");
            }
            totalAmount = totalAmount.add(goods.getPrice().multiply(new BigDecimal(goodsNum))).subtract(itemInfo.getCouponAmount());
        }
        //订单优惠券
        if (ObjectUtil.isNotNull(orderInfo.getCouponId())) {
            CouponInfo couponInfo = couponService.getById(orderInfo.getCouponId());
            if (couponInfo == null) {
                throw new RuntimeException("优惠券不存在");
            }
        } else {
            if (orderInfo.getCouponAmount().compareTo(BigDecimal.ZERO) > 0) {
                throw new RuntimeException("缺少订单优惠券信息");
            }
        }

        if (!orderAmount.subtract(orderInfo.getCouponAmount()).equals(totalAmount)) {
            throw new RuntimeException("商品总价计算错误！");
        }
    }


    private boolean isNumeric(String s) {
        if (s != null && !"".equals(s.trim())) {
            return s.matches("^[0-9]*$");
        } else {
            return false;
        }
    }

}
